home *** CD-ROM | disk | FTP | other *** search
- const char *Version=
- "AFS Version 1 - AF string finder for One Must Fall 2097 .AF files\n"
- "By Kenneth F. Henderson Jr. (71672,1777)";
- /*
- This code is, of course, provided AS IS, with no waranty or anything else.
- Copy it, rewrite it, use it, FUBAR it, whatever you like (I would prefer that
- you include the above credits if you redistribute it, BTW), however no matter
- what happens none of the aforementioned people can be held responsible, whether
- your hard disk crashes, your computer dies, OMF decides to cheat on you every
- time you play, or anything else. <grin>
-
- WARNING: The Borland C++ project file that accompanies this code turns
- 386 instructions ON, on the premise that since OMF requires a 386, all
- machines running this code will have at least a 386. The included .COM file
- was compiled using this project file, so it may very well hang (or worse)
- on a lesser machine unless recompiled with the option set down to whatever
- you're using.
-
- For basic usage instructions, just run the program with no parameters.
-
- This program extracts the location and contents of everything that looks like
- an AF move string or keystroke sequence from .AF files. The output format
- should be largely self-explanitory. "M" is a move string which fits perfectly
- within its field, without a null. "m" is a move string which has a null tacked
- on the end - typically a move executed by the opponent when hit. "K" is a
- keystroke.
-
- To create a full set of AFS files for the basic AFs, first make sure you're
- using your original .AF files. Then run the AFSAll.Bat batch file included.
- It will run AFS on each Fightr*.AF file, and then make the resulting .AFS files
- read-only so you don't accidentally overwrite them. The process should take
- about 5-10 minutes and should only need to be done once, unless the .AF files
- change. (So far, the only changes have been trivial keystroke modifications
- which are documented in my FAQ.) Assuming you backup the .ZIP file this came
- in, you can then delete AFSAll.Bat to save space.
-
- Below is the actual C source code. Hackers only. B-)
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <alloc.h>
-
- // Return codes (RET_)
- //These codes may change from version to version
- //If you use them, always check for changes when you get a new version
- #define RET_Normal 0
- #define RET_BadParms -1
- #define RET_BadFile -2
- #define RET_BadClose -3
- #define RET_OutOfMemory -4
-
- const char ValidH= '~'; //Highest valid character
- const char ValidL= ' '; //Lowest valid character
-
- int FindStrings(FILE *FileIn,FILE *FileOut,
- unsigned char *Buffer,size_t BufferSize)
- {
- unsigned char c,*d,*dmax=Buffer+BufferSize,CouldBeMove,CouldBeKeys;
- unsigned long FileSize,FilePos=0,StrLoc;
- unsigned int StrSize;
-
- //Get length of input file
- fseek(FileIn,0,SEEK_END);
- FileSize=ftell(FileIn);
- fseek(FileIn,0,SEEK_SET);
-
- while(FilePos<FileSize)
- {
- c=fgetc(FileIn);
- FilePos++;
-
- //Ignore chars outside 21-7E
- if(c>ValidH || c<ValidL)
- continue;
-
- //Reset buffer
- d=Buffer;
- StrLoc=FilePos-1; //PREVIOUS character
- CouldBeMove=1; //Used as Boolean
- CouldBeKeys=0; //Used as size of keystroke
-
- //Store char
- *(d++)=c;
-
- //Inner loop: Scan string
- while(1)
- {
- //See if char is not found in AF move strings
- if( !isalnum(c) && (c!='-') && (c!='+') )
- CouldBeMove=CouldBeKeys=0;
- else
- {
- //If it could be found in a move, it could be found
- //in a keystroke. Check for keystroke
- if(!CouldBeKeys)
- {
- if( (c=='P') || (c=='K') )
- CouldBeKeys=1;
- }
- else if( isdigit(c) )
- CouldBeKeys++;
- else
- CouldBeKeys=0;
- }
-
- //Check for end of file
- if( FilePos>=FileSize )
- break;
-
- //Check for end of buffer
- if(d>=dmax)
- {
- printf("String at %08lX too long to process!\n",StrLoc);
- break;
- }
-
- //Get next char
- c=fgetc(FileIn);
- FilePos++;
- *(d++)=c;
-
- //Upon reaching end of string, test and write
- if(c>ValidH || c<ValidL)
- {
- //Null terminate (decrement because of above)
- *(--d)=0;
-
- //Good place to check record keeping
- if(FilePos!=ftell(FileIn))
- puts("File position failed consistency check!");
-
- //Get what could be a field size
- fseek(FileIn,StrLoc-2,SEEK_SET);
- fread(&StrSize,1,sizeof(StrSize),FileIn);
- fseek(FileIn,FilePos,SEEK_SET);
-
- //AF move strings must end in a digit and contain at
- //least one '-'
- if( CouldBeMove &&
- isdigit(*(d-1)) &&
- strchr(Buffer,'-') )
- {
- int i=strlen(Buffer);
-
- //Check for valid size
- if(StrSize==i)
- {
- fprintf(FileOut,"%08lX:M:%s\n",
- StrLoc,Buffer);
- putchar('.');
- break;
- }
- //Check for valid size + null - commonly seen
- //in hit frame sequences. Odd.
- else if(StrSize==i+1 && !c)
- {
- fprintf(FileOut,"%08lX:m:%s\n",
- StrLoc,Buffer);
- putchar('.');
- break;
- }
- }
-
- //Keystrokes must have a double-null and be 1-20 chars
- if( CouldBeKeys &&
- !c &&
- !(FilePos++,fgetc(FileIn)) &&
- CouldBeKeys<21
- )
- {
- char* Keystroke;
-
- //Adjust to show only the keystroke
- if( !(Keystroke=strrchr(Buffer,'P')) &&
- !(Keystroke=strrchr(Buffer,'K')) )
- {
- puts("MAJOR consistency error in keystroke scan!");
- break;
- }
- StrLoc+=(Keystroke-Buffer);
-
- fprintf(FileOut,"%08lX:K:%s\n",
- StrLoc,Keystroke);
- putchar('.');
- break;
- }
-
- //Code to output questionable strings could go here
- //if desired; currently unneeded.
- break;
- }
- }
- }
- putchar('\n');
- if(FilePos!=FileSize||FilePos!=ftell(FileIn))
- puts("Warning: Possible error in offsets.");
- return RET_Normal;
- }
-
- int _cdecl main(int argc,unsigned char *argv[])
- {
- FILE *FileIn,*FileOut;
- char *FileInName,*FileOutName;
- char FileOutTemp[128];
- unsigned char *Buffer;
- size_t BufferSize;
- int i;
- const char *FileOpenError="Couldn't open file: %s\n";
-
- puts(Version);
- if(argc<2)
- {
- puts("Usage: AFS <Input AF File> [Output AFS File]");
- exit(RET_BadParms);
- }
-
- FileInName=argv[1];
-
- if(argc<3)
- {
- char *c;
-
- strcpy(FileOutTemp,FileInName);
-
- c=strrchr(FileOutTemp,'.');
- if(!c)
- c=strrchr(FileOutTemp,0);
-
- strcpy(c,".AFS");
-
- FileOutName=FileOutTemp;
- }
- else
- FileOutName=argv[2];
-
-
- printf( "AF : %s\n"
- "AFS : %s\n",FileInName,FileOutName);
-
- if(!(FileIn=fopen(FileInName,"rb")))
- {
- printf(FileOpenError,FileInName);
- return RET_BadFile;
- }
- if(!(FileOut=fopen(FileOutName,"wt")) )
- {
- printf(FileOpenError,FileOutName);
- return RET_BadFile;
- }
-
- //Allocate all available near memory as buffer
- if(!(Buffer=(unsigned char *)malloc(BufferSize=coreleft())))
- {
- puts("Could not allocate available memory as buffer!");
- return RET_OutOfMemory;
- }
- printf("Buffer: %u bytes.\n",BufferSize);
-
- i=FindStrings(FileIn,FileOut,Buffer,BufferSize);
-
- free(Buffer);
-
- if(fclose(FileIn)|fclose(FileOut))
- {
- puts("Error closing file(s)!");
- return RET_BadClose;
- }
-
- return i;
- }
-